#include "hyMath.h"

QStack<double> HYMath::m;
QStack<char> HYMath::s;

HYMath::HYMath()
{
}

void HYMath::Read()
{
    bool ok;
    for (int i = 0; i < inputStr.count(); i++)
    {
        if (!IsOperator(inputStr[i]))
        {
            QString str = QString();
            while (i < inputStr.count() && !IsOperator(inputStr[i]))
            {
                str += inputStr[i];
                i++;
            }
            i--;
            double dtp = str.toDouble(&ok);
            m.push(dtp);
        }
        else if (IsOper(inputStr[i]))
        {
            if (s.isEmpty() || s.top() == QChar('('))
            {
                s.push(inputStr[i]);
            }
            else if (OperatorPrecedence(inputStr[i]) > OperatorPrecedence(s.top()))
            {
                s.push(inputStr[i]);
            }
            else
            {
                double n1 = 0, n2 = 0;
                char s1 = 0;
                if (!m.isEmpty())
                    n2 = m.pop();
                if (!m.isEmpty())
                    n1 = m.pop();
                if (!s.pop())
                    s1 = s.pop();
                double sum = Operat(n1, n2, s1);
                m.push(sum);
                s.push(inputStr[i]);
            }
        }
        else
        {
            if (inputStr[i] == QChar('('))
            {
                s.push(inputStr[i]);
            }
            else if (inputStr[i] == QChar(')'))
            {
                while (!s.top() == QChar('('))
                {
                    double n1 = 0, n2 = 0;
                    char s1 = 0;
                    if (!m.isEmpty())
                        n2 = m.pop();
                    if (!m.isEmpty())
                        n1 = m.pop();
                    if (!s.pop())
                        s1 = s.pop();
                    double sum = Operat(n1, n2, s1);
                    m.push(sum);
                }
                s.pop();
            }
        }
    }
}

double HYMath::PopStack()
{
    double sum = 0;
    while (s.count() != 0)
    {
        double n1 = 0, n2 = 0;
        char s1 = 0;
        if (!m.isEmpty())
            n2 = m.pop();
        if (!m.isEmpty())
            n1 = m.pop();
        if (!s.pop())
            s1 = s.pop();
        sum = Operat(n1, n2, s1);
        m.push(sum);
    }
    return sum;
}

bool HYMath::IsOperator(char c)
{
    if (c == QChar('+') || c == QChar('-') || c == QChar('*') || c == QChar('/') || c == QChar('(') || c == QChar(')'))
        return true;
    return false;
}

bool HYMath::IsOper(char c)
{
    if (c == QChar('+') || c == QChar('-') || c == QChar('*') || c == QChar('/'))
        return true;
    return false;
}

int HYMath::OperatorPrecedence(char a)
{
    int i = 0;
    switch (a)
    {
    case '+':
        i = 3;
        break;
    case '-':
        i = 3;
        break;
    case '*':
        i = 4;
        break;
    case '/':
        i = 4;
        break;
    }
    return i;
}

double HYMath::Operat(double n1, double n2, char s1)
{
    double sum = 0;
    switch (s1)
    {
    case '+':
        sum = n1 + n2;
        break;
    case '-':
        sum = n1 - n2;
        break;
    case '*':
        sum = n1 * n2;
        break;
    case '/':
        sum = n1 / n2;
        break;
    }
    return sum;
}

QString HYMath::DataMain()
{
    Read();
    double td = PopStack();

    return QString::number(td);
}
